package sk.stuba.fiit.ltasys.web.mvc.model.dao.impl;

import java.math.BigInteger;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import sk.stuba.fiit.ltasys.web.mvc.model.dao.CrlAndCertDao;
import sk.stuba.fiit.ltasys.web.mvc.model.entity.CertificateEntity;
import sk.stuba.fiit.ltasys.web.mvc.model.entity.CrlEntity;

@Repository("crlAndCertDaoImpl")
@Transactional(readOnly = true)
public class CrlAndCertDaoImpl implements CrlAndCertDao{

	@Autowired
	protected SessionFactory sessionFactory = null;
	
	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		template = new HibernateTemplate(sessionFactory);
	}
	
	protected HibernateTemplate template = null;
	
	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	public void saveCertificate(CertificateEntity certificate) {
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		session.saveOrUpdate(certificate);
		transaction.commit();
		session.close();
	}

	public CertificateEntity getCertificateByIssuerAndSerialNumber(String issuer,BigInteger serialNum) {
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		@SuppressWarnings("unchecked")
		List<CertificateEntity> result = session.createCriteria(CertificateEntity.class).
//				add(Restrictions.eq(CertificateEntity.ISSUER, issuer)).
				add(Restrictions.eq(CertificateEntity.SERIAL_NUMBER, serialNum)).list();
		
		transaction.rollback();
		session.close();
		if(result.size()==0)
			return new CertificateEntity();
		return result.get(0);
	}
	
	public CertificateEntity getCertificateBySubject(String subject) {
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		List<CertificateEntity> result = session.createCriteria(CertificateEntity.class).
				add(Restrictions.eq(CertificateEntity.SUBJECT, subject)).list();
		
		transaction.rollback();
		session.close();
		if(result.size()==0)
			return new CertificateEntity();
		return result.get(0);
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	public void deleteCertificate(CertificateEntity certificate) {
		template.delete(certificate);
	}
	
	
	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	public void saveCrl(CrlEntity crl) {
		template.saveOrUpdate(crl);
	}

	public CrlEntity getActualCrl(String issuer,BigInteger serialNum) {
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Criteria criteria = session.createCriteria(CrlEntity.class);
		if(issuer!= null){
			criteria.add(Restrictions.eq(CrlEntity.ISSUER, issuer));
		}
		criteria.addOrder(Order.desc("updateTime"));
		List<CrlEntity> result = criteria.list();
		transaction.rollback();
		session.close();
		if(result.size()==0)
			return new CrlEntity();
		return result.get(0);
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	public void deleteCrl(CrlEntity crl) {
		template.delete(crl);
	}


}
